home *** CD-ROM | disk | FTP | other *** search
/ Fritz: All Fritz / All Fritz.zip / All Fritz / FILES / PROGNG_C / CUTILV1.LZH / CRC.C < prev    next >
Text File  |  1984-07-29  |  5KB  |  131 lines

  1. /******************************************
  2. *                      *
  3. * Cyclic Redundancy Check (CRC) functions *
  4. *                      *
  5. ******************************************/
  6.  
  7. /*
  8. *   crc_clear:
  9. *    This function clears the CRC to zero. It should be called prior to
  10. *    the start of the processing of a block for both received messages,
  11. *    and messages to be transmitted.
  12. *
  13. *    Calling sequence:
  14. *
  15. *    short crc;
  16. *    crc = crc_clear();
  17. */
  18. short crc_clear()
  19. {
  20.     return(0);
  21. }
  22. /*
  23. *   crc_update:
  24. *    this function must be called once for each character which is
  25. *    to be included in the CRC for messages to be transmitted.
  26. *    This function is called once for each character which is included
  27. *    in the CRC of a received message, AND once for each of the two CRC
  28. *    characters at the end of the received message. If the resulting
  29. *    CRC is zero, then the message has been correctly received.
  30. *
  31. *   Calling sequence:
  32. *
  33. *    crc = crc_update(crc,next_char);
  34. */
  35. short crc_update(crc,crc_char)
  36. short crc;
  37. char crc_char;
  38. {
  39.     long x;
  40.     short i;
  41.  
  42. /* "x" will contain the character to be processed in bits 0-7 and the CRC    */
  43. /* in bits 8-23. Bit 24 will be used to test for overflow, and then cleared  */
  44. /* to prevent the sign bit of "x" from being set to 1. Bits 25-31 are not    */
  45. /* used. ("x" is treated as though it is a 32 bit register).                 */
  46.     x = ((long)crc << 8) + crc_char;    /* Get the CRC and the character */
  47.  
  48. /* Repeat the following loop 8 times (for the 8 bits of the character).      */
  49.     for(i = 0;i < 8;i++)
  50.     {
  51.  
  52. /* Shift the high-order bit of the character into the low-order bit of the   */
  53. /* CRC, and shift the high-order bit of the CRC into bit 24.             */
  54.         x = x << 1;               /* Shift "x" left one bit */
  55.  
  56. /* Test to see if the old high-order bit of the CRC was a 1.             */
  57.         if(x & 0x01000000)               /* Test bit 24 of "x" */
  58.  
  59. /* If the old high-order bit of the CRC was a 1, exclusive-or it with a one  */
  60. /* to set it to 0, and exclusive-or the CRC with hex 1021 to produce the     */
  61. /* CCITT-recommended CRC generator of: X**16 + X**12 + X**5 + 1. To produce  */
  62. /* the CRC generator of: X**16 + X**15 + X**2 + 1, change the constant from  */
  63. /* 0x01102100 to 0x01800500. This will exclusive-or the CRC with hex 8005    */
  64. /* and produce the same CRC that IBM uses for their synchronous transmission */
  65. /* protocols.                                     */
  66.             x = x ^ 0x01102100;    /* Exclusive-or "x" with a...*/
  67.                           /* ...constant of hex 01102100 */
  68. /* And repeat 8 times.                                 */
  69.     }                        /* End of "for" loop */
  70.  
  71. /* Return the CRC as the 16 low-order bits of this function's value.         */
  72.     return(((x & 0x00ffff00) >> 8)); /* AND off the unneeded bits and... */
  73.                   /* ...shift the result 8 bits to the right */
  74.  
  75. }
  76. /*
  77. *   crc_finish:
  78. *    This function must be called once after all the characters in a block
  79. *    have been processed for a message which is to be TRANSMITTED. It
  80. *    returns the calculated CRC bytes, which should be transmitted as the
  81. *    two characters following the block. The first of these 2 bytes
  82. *    must be taken from the high-order byte of the CRC, and the second
  83. *    must be taken from the low-order byte of the CRC. This routine is NOT
  84. *    called for a message which has been RECEIVED.
  85. *
  86. *   Calling sequence:
  87. *
  88. *    crc = crc_finish(crc);
  89. */
  90. short crc_finish(crc)
  91. short crc;
  92. {
  93. /* Call crc_update twice, passing it a character of hex 00 each time, to     */
  94. /* flush out the last 16 bits from the CRC calculation, and return the         */
  95. /* result as the value of this function.                     */
  96.     return(crc_update(crc_update(crc,'\0'),'\0'));
  97.  
  98. }
  99.  
  100. /*
  101. * This is a sample of the use of the CRC functions, which calculates the
  102. * CRC for a 1-character message block, and then passes the resulting CRC back
  103. * into the CRC functions to see if the "received" 1-character message and CRC
  104. * are correct.
  105. */
  106. main()
  107. {
  108.  
  109.     short crc;                       /* The calculated CRC */
  110.     char crc_char;                  /* The 1-character message */
  111.     char x, y;          /* 2 places to hold the 2 "received" CRC bytes */
  112.  
  113.     crc_char = 'A';                    /* Define the 1-character message */
  114.     crc = crc_clear();    /* Reset the CRC to "transmit" a new message */
  115.     crc = crc_update(crc,crc_char);   /* Update the CRC for the first... */
  116.                    /* ...(and only) character of the message */
  117.     crc = crc_finish(crc);          /* Finish the transmission calculation */
  118.     x = (char)((crc & 0xff00) >> 8);  /* Extract the high-order CRC byte */
  119.     y = (char)(crc & 0x00ff);       /* And extract the low-order byte */
  120.     printf("%04x\n",crc);                           /* Print the results */
  121.  
  122.     crc = crc_clear();           /* Prepare to "receive" a message */
  123.     crc = crc_update(crc,crc_char);   /* Update the CRC for the first... */
  124.                    /* ...(and only) character of the message */
  125.     crc = crc_update(crc,x);     /* Pass both bytes of the "received"... */
  126.     crc = crc_update(crc,y);       /* ...CRC through crc_update, too */
  127.     printf("%04x\n",crc);    /* If the result was 0, then the message... */
  128.                         /* ...was received without error */
  129.  
  130. }
  131.